// @Date         2021-11-18
// @Author       Aaron Zhang
// @Description	 创建Provider模板
// @FileName      provider.go

package template

import (
	"errors"
	"fmt"
	"os"
	"path"
	"path/filepath"
	"strings"
	"zin/framework/util"
)

var FileArr = []string{}

func getReplaceContent(content, pName, description string) string {
	dateTime := util.ConvertNowDate2String(util.DateFormat2)
	uName := util.StrFirstToUpper(pName)

	content = strings.Replace(content, "{name}", pName, strings.Count(content, "{name}"))
	content = strings.Replace(content, "{uName}", uName, strings.Count(content, "{uName}"))
	content = strings.Replace(content, "{date}", dateTime, strings.Count(content, "{date}"))
	content = strings.Replace(content, "{description}", description, strings.Count(content, "{description}"))

	return content
}

func putContentToFile(pName, fileName, content string) error {
	appService := util.GetAppProvider()

	providerFolder := appService.ProviderFolder()
	filePath := path.Join(providerFolder, pName, fileName)

	// check provider dir is exists
	if exists, _ := util.PathExists(filePath); exists {
		return errors.New(fmt.Sprintf("provider  %s exists ", filePath))
	}

	//创建文件夹
	fs, _ := os.Stat(filePath)
	if fs == nil {
		err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm)
		if err != nil {
			return errors.New(fmt.Sprintf("create dir failed : %v", err))
		}
	}

	fileObj, fErr := os.OpenFile(filePath, os.O_CREATE|os.O_RDWR, os.ModePerm)

	if fErr != nil {
		return errors.New(fmt.Sprintf("open file  %s failed : %v", fileName, fErr))
	}

	_, cErr := fileObj.WriteString(content)
	if cErr != nil {
		return errors.New(fmt.Sprintf("write file %s failed : %v", fileName, cErr))
	}

	FileArr = append(FileArr, filePath)

	return nil
}

// CreateProviderContract 创建Contract接口文件
func CreateProviderContract(pName, description string) error {
	content := `// @Date         {date}
// @Author       Aaron Zhang
// @Description   {description}
// @FileName      contract.go   

package {name}

const ProviderKey{uName} = "pk:{name}"

type IContract{uName} interface {

}
`

	fContent := getReplaceContent(content, pName, description)
	return putContentToFile(pName, "contract.go", fContent)

}

// CreateProviderProvider    创建Provider文件
func CreateProviderProvider(pName, description string, isDefer bool) error {
	providerContent := `// @Date         {date}
// @Author       Aaron Zhang
// @Description  {description}
// @FileName      provider.go   

package {name}

import (
	"zin/framework"
)

type Provider{uName} struct {
}

func (d *Provider{uName}) Register(framework.Container) framework.NewInstance {
	return NewProviderService{uName}
}

// boot负责配置初始化
func (d *Provider{uName}) Boot(framework.Container) error {
	return nil
}

//isDefer控制什么时候初始化
func (d *Provider{uName}) IsDefer() bool {
	return %v
}

func (d *Provider{uName}) Params(params map[string]interface{}) map[string]interface{} {
	return params
}

func (d *Provider{uName}) Name() string {
	return ProviderKey{uName}
}
`
	content := getReplaceContent(providerContent, pName, description)
	content = fmt.Sprintf(content, isDefer)

	fContent := getReplaceContent(content, pName, description)
	return putContentToFile(pName, "provider.go", fContent)

}

// CreateProviderService 创建service文件
func CreateProviderService(pName, description string) error {
	serviceContent := `// @Date        {date}
// @Author       Aaron Zhang
// @Description   {description}
// @FileName      service.go

package {name}

type ProviderService{uName} struct {
}

func NewProviderService{uName}(params map[string]interface{}) (interface{}, error) {

	return &ProviderService{uName}{
		
	}, nil
}

`
	fContent := getReplaceContent(serviceContent, pName, description)
	return putContentToFile(pName, "service.go", fContent)

}
